package Factory.Entities;

import Model.Core.Impl.ObjectEntity;
import Model.Diagrams.StateMachine;
import Model.Draw.Coordinate;
import Model.Draw.Entities.Impl.ObjectLine;
import Model.Draw.Entities.ObjectDraw;
import Model.Draw.Events.ManifestEntityDoneListener;
import Model.Draw.Events.ManifestElementEvent;
import Model.Draw.Events.ManifestStateEvent;
import Model.Draw.Point;
import java.util.ArrayList;
import java.util.List;

/**
 * Projeto de TCC: Editor de Diagramas de comunicação BlueJ
 * @author Jose
 */
public class ObjectFactory {

    private List<ManifestEntityDoneListener> listeners;

    public ObjectFactory() {
        listeners = new ArrayList<ManifestEntityDoneListener>();
    }

    public void addListener(ManifestEntityDoneListener listener) {
        if (!listeners.contains(listener)) {
            this.listeners.add(listener);
        }
    }

    public void removeListener(ManifestEntityDoneListener listener) {
        this.listeners.remove(listener);
    }

    public void createEntityGraphicalManifest(ObjectEntity objectEntity, Object sourceElement, Object targetElement) {
        Point startPoint = (Point) sourceElement;
        Point finalPoint = (Point) targetElement;
        Point aux;
        if (startPoint.getX().getCoordinate() > finalPoint.getX().getCoordinate()) {
            if (startPoint.getY().getCoordinate() > finalPoint.getY().getCoordinate()) {
                aux = new Point(new Coordinate(startPoint.getX().getCoordinate()), new Coordinate(startPoint.getY().getCoordinate()));
                startPoint = finalPoint;
                finalPoint = aux;
            } else {
                aux = new Point(new Coordinate(startPoint.getX().getCoordinate()), new Coordinate(startPoint.getY().getCoordinate()));
                startPoint.setX(finalPoint.getX());
                finalPoint.setX(aux.getX());
            }
        } else {
            if (startPoint.getY().getCoordinate() > finalPoint.getY().getCoordinate()) {
                aux = new Point(new Coordinate(startPoint.getX().getCoordinate()), new Coordinate(startPoint.getY().getCoordinate()));
                startPoint.setY(finalPoint.getY());
                finalPoint.setY(aux.getY());
            }
        }
        ObjectDraw graphicalManifest = new ObjectDraw();
        graphicalManifest.setEntity(objectEntity);
        Point supportPointY = new Point(finalPoint.getX(), startPoint.getY());
        Point supportPointX = new Point(startPoint.getX(), finalPoint.getY());
        graphicalManifest.setTop(new ObjectLine(startPoint, supportPointY, objectEntity));
        graphicalManifest.setRight(new ObjectLine(supportPointY, finalPoint, objectEntity));
        graphicalManifest.setLeft(new ObjectLine(startPoint, supportPointX, objectEntity));
        graphicalManifest.setBottom(new ObjectLine(supportPointX, finalPoint, objectEntity));
        notifyEntityListeners(graphicalManifest);
        notifyStateListeners(objectEntity.getStateMachine());
    }

    private void notifyEntityListeners(ObjectDraw graphicalManifest) {
        for (ManifestEntityDoneListener listener : listeners) {
            listener.manifestEntityDoneHandler(new ManifestElementEvent(graphicalManifest));
        }
    }
    
    private void notifyStateListeners(StateMachine stateMachine){
        for(ManifestEntityDoneListener listener : listeners){
            listener.manifestStateMachineDoneHandler(new ManifestStateEvent(stateMachine));
        }
    }
}